package com.gopay.webtest.controller;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.gopay.webtest.util.SignUtil;

import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.gopay.webtest.util.BaseSign;
import com.gopay.webtest.util.Encrypt;
import com.gopay.webtest.vo.CommonResp;
import com.gopay.webtest.vo.GuaranteeApplyResp;

@RequestMapping("/result/webclient/front")
@Controller
public class WebClientResultProController {

    private static Logger logger = Logger.getLogger(WebClientResultProController.class);

    @Resource(name = "signHandler")
    private Map<String, Object> signHandler = new HashMap<String, Object>();

    @RequestMapping("/recv")
    public ModelAndView execute(HttpServletRequest request, HttpServletResponse response) {
        // set charset gbk
        try {
            request.setCharacterEncoding("gbk");
        } catch (UnsupportedEncodingException e1) {
            logger.error(e1);
        }
        String repCode = request.getParameter("respCode");
        logger.info("recive respone code : " + repCode);
        if (repCode == null) {
            return null;
        }

        logger.info("request charset info: " + request.getCharacterEncoding());

        ModelAndView mv = new ModelAndView("gopay.webtest.front_res_info_trans_gbk");
        ServletRequestDataBinder binder = null;
        logger.info("************************* 接收到返回参数 *****************************");

        String verficationCode = "";

        String transCode = request.getParameter("tranCode");

        logger.info("rquest transCode is : " + transCode);

        String signTransCode = null;
        BaseSign handler = null;
        if (transCode != null && !"".equals(transCode)) {
            // get parameter version
            String version = request.getParameter("version");

            // get the sign handler
            if ("9999".equals(transCode) || "4010".equals(transCode)) {
                signTransCode = transCode;
                handler = (BaseSign) signHandler.get(transCode);

            } else if ("GP05".equals(transCode) || "GP01".equals(transCode) || "GP02".equals(transCode)
                    || "GP03".equals(transCode) || "GS01".equals(transCode)) {
                if ("GS01".equals(transCode)) {
                    signTransCode = transCode + "_RESP_PC";
                    handler = (BaseSign) signHandler.get(signTransCode);
                } else {
                    signTransCode = transCode + "_RESP";
                    handler = (BaseSign) signHandler.get(signTransCode);
                }
            } else if ("GS06".equals(transCode)) {// G商融通 继续往下加
                signTransCode = transCode + "_2.1_PC";
                handler = (BaseSign) signHandler.get(signTransCode);
            } else if ("GS03".equals(transCode) || "GS09".equals(transCode) || "GS02".equals(transCode)) {
                // 充值/提现/还款，返回报文加密与上传加密字段不一致，单独处理
                signTransCode = transCode + "_2.1_PC" + "_RESP";
                handler = (BaseSign) signHandler.get(signTransCode);
            } else {
                signTransCode = transCode + "_" + version;
                handler = (BaseSign) signHandler.get(signTransCode);
            }

            if ("9999".equals(transCode)) {
                //
                logger.info("starting binding parameter from request ...");

                GuaranteeApplyResp payinfo = new GuaranteeApplyResp();

                // CommonResp resp = new CommonResp();
                binder = new ServletRequestDataBinder(payinfo);

                binder.bind(request);

                verficationCode = getVerfiCode(payinfo.getFrontMerUrl());
                Encrypt en;
                try {
                    payinfo.setVerficationCode(verficationCode);
                } catch (Exception e1) {
                    logger.error(e1);
                }

                // if ("1".equals(payinfo.getCharset())) {
                mv.setViewName("gopay.webtest.front_res_info_trans_9999_gbk");

                logger.info("ending binding parameter from request ...");

                logger.info("ready to encrypted message with md5 or sha ...");

                logger.info("prepare to get the sign fields...");

                String origSignMsg = payinfo.getSignValue();

                try {
                    // 进行加签
                    handler.sign(signTransCode, "signType", "signValue", payinfo, request);
                } catch (Exception e) {
                    logger.error(e);
                    payinfo.setRespCode("MR08");
                    payinfo.setMsgExt("本地加签失败");
                    mv.addObject("payinfo", payinfo);

                    mv.setViewName("gopay.webtest.front_res_info_trans_9999_gbk");

                    return mv;
                }

                // Attestation not through
                if (!origSignMsg.equals(payinfo.getSignValue())) {
                    payinfo.setRespCode("MR07");
                    payinfo.setMsgExt("本地验签失败");
                    logger.info("Attestation not through...");
                    mv.addObject("payinfo", payinfo);

                    mv.setViewName("gopay.webtest.front_res_info_trans_9999_gbk");

                    return mv;
                } else {

                    logger.info("Attestation by...");
                    mv.setViewName("gopay.webtest.front_res_info_trans_9999_gbk");

                    mv.addObject("payinfo", payinfo);

                    return mv;
                }
            } else if ("GP05".equals(transCode) || "GP01".equals(transCode) || "GP02".equals(transCode)
                    || "GP03".equals(transCode) || "GS01".equals(transCode)) {
                logger.info("execute P2P relation ...");
                logger.info("starting binding parameter from request ...");

                CommonResp resp = new CommonResp();

                binder = new ServletRequestDataBinder(resp);

                binder.bind(request);

                verficationCode = getVerfiCode(resp.getFrontMerUrl());

                try {
                    resp.setVerficationCode(verficationCode);
                } catch (Exception e1) {
                    logger.error(e1);
                }
                if ("GP05".equals(resp.getTranCode())) {
                    mv.setViewName("p2p.bind.front_res_info_trans");
                } else if ("GP01".equals(resp.getTranCode())) {
                    mv.setViewName("p2p.recharge.front_res_info_trans");
                } else if ("GP02".equals(resp.getTranCode())) {
                    mv.setViewName("p2p.draw.front_res_info_trans");
                } else if ("GP03".equals(resp.getTranCode())) {
                    mv.setViewName("p2p.transfer.front_res_info_trans");
                } else if ("GS01".equals(resp.getTranCode())) {
                    mv.setViewName("gopay.webtest.listdocustsigned");
                }

                logger.info("ending binding parameter from request ...");

                String origSignMsg = resp.getSignValue();

                try {
                    logger.info("ready to encrypted message with md5 or sha ...");
                    // 进行加签
                    handler.sign(signTransCode, "signType", "signValue", resp, request);
                    logger.info("end encrypted message with md5 or sha ...");
                } catch (Exception e) {
                    resp.setRespCode("MR08");
                    resp.setMsgExt("本地加签失败");
                    mv.addObject("payinfo", resp);
                    e.printStackTrace();
                    return mv;
                }

                // Attestation not through
                if (!origSignMsg.equals(resp.getSignValue())) {
                    logger.info("not equal encrypted message ...");
                    resp.setRespCode("MR07");
                    resp.setMsgExt("本地验签失败");
                    logger.info("Attestation not through...");
                    mv.addObject("payinfo", resp);

                    return mv;
                } else {
                    logger.info("equal encrypted message ...");
                    logger.info("Attestation by...");
                    mv.addObject("payinfo", resp);
                    return mv;
                }

            } else if ("GS06".equals(transCode) || "GS03".equals(transCode) || "GS09".equals(transCode)
                    || "GS02".equals(transCode)) {// G商融通

                logger.info("starting binding parameter from request ...");

                CommonResp resp = new CommonResp();

                binder = new ServletRequestDataBinder(resp);

                binder.bind(request);
                String remark = resp.getRemark();
                String MsgExt = resp.getMsgExt();
                try {
                    // remark.getBytes("iso8859-1");
                    if (StringUtils.isNotBlank(remark)) {
                        remark = new String(remark.getBytes("iso-8859-1"), "UTF-8");
                        resp.setRemark(remark);
                    }
                    MsgExt = new String(MsgExt.getBytes("iso-8859-1"), "UTF-8");
                    resp.setMsgExt(MsgExt);
                } catch (UnsupportedEncodingException e2) {
                    logger.error(e2);
                }
                verficationCode = getVerfiCode(resp.getFrontMerUrl());

                try {
                    resp.setVerficationCode(verficationCode);
                } catch (Exception e1) {
                    logger.error(e1);
                }

                logger.info("ending binding parameter from request ...");

                String origSignMsg = resp.getSignValue();

                try {
                    logger.info("ready to encrypted message with md5 or sha ...");
                    // 进行加签

                    handler.sign(signTransCode, "signType", "signValue", resp, request);
                    logger.info("end encrypted message with md5 or sha ...");
                } catch (Exception e) {
                    resp.setRespCode("MR08");
                    resp.setMsgExt("本地加签失败");
                    mv.addObject("payinfo", resp);
                    e.printStackTrace();
                    return mv;
                }
                if ("GS06".equals(resp.getTranCode())) {
                    mv.setViewName("gopay.webtest.listdobid");
                }
                if ("GS02".equals(resp.getTranCode())) {
                    mv.setViewName("gopay.webtest.listShowRecharge");
                }
                if ("GS09".equals(resp.getTranCode())) {
                    mv.setViewName("gopay.webtest.listShowRepay");
                }
                if ("GS03".equals(resp.getTranCode())) {
                    mv.setViewName("gopay.webtest.listShowDraw");
                }
                // // Attestation not through
                if (!origSignMsg.equals(resp.getSignValue())) {
                    logger.info("not equal encrypted message ...");
                    resp.setRespCode("MR07");
                    resp.setMsgExt("本地验签失败");
                    logger.info("Attestation not through...");
                    mv.addObject("payinfo", resp);

                    return mv;
                } else {

                    logger.info("equal encrypted message ...");
                    logger.info("Attestation by...");
                    mv.addObject("payinfo", resp);
                    return mv;
                }

            } else {

                logger.info("starting binding parameter from request ...");

                CommonResp resp = new CommonResp();

                binder = new ServletRequestDataBinder(resp);

                binder.bind(request);

                verficationCode = getVerfiCode(resp.getFrontMerUrl());

                try {
                    resp.setVerficationCode(verficationCode);
                } catch (Exception e1) {
                    logger.error(e1);
                }

                mv.setViewName("gopay.webtest.front_res_info_trans_gbk");

                logger.info("ending binding parameter from request ...");

                String origSignMsg = resp.getSignValue();

                //得到国付宝加签的原串
                String signType = resp.getSignType();
                String signStrb = null;
                try {
                    logger.info("ready to encrypted message with md5 or sha ...");
                    if("3".equals(signType)){
                        signStrb = handler.getSignStr(signTransCode,resp);
                    }else{
                        // 进行加签
                        handler.sign(signTransCode, "signType", "signValue", resp, request);
                        logger.info("end encrypted message with md5 or sha ...");
                    }
                } catch (Exception e) {
                    resp.setRespCode("MR08");
                    resp.setMsgExt("本地加签失败");
                    mv.addObject("payinfo", resp);
                    e.printStackTrace();
                    return mv;
                }


                //api验签
                if("3".equals(signType)){
                    //进行加签验证
                    boolean bverify = SignUtil.doCheck(signStrb,origSignMsg);
                    if(!bverify) {
                        logger.info("api证书验签失败 ...");
                        resp.setRespCode("MR07");
                        resp.setMsgExt("本地验签失败");
                        logger.info("Attestation not through...");
                        mv.addObject("payinfo", resp);

                        return mv;
                    }else{
                        logger.info("api证书验签成功 ......");
                        logger.info("Attestation by...");
                        mv.setViewName("gopay.webtest.front_res_info_trans");
                        mv.addObject("payinfo", resp);
                        return mv;
                    }

                }else {
                    // Attestation not through  原有验签
                    if (!origSignMsg.equals(resp.getSignValue())) {
                        logger.info("not equal encrypted message ...");
                        resp.setRespCode("MR07");
                        resp.setMsgExt("本地验签失败");
                        logger.info("Attestation not through...");
                        mv.addObject("payinfo", resp);

                        return mv;
                    } else {
                        logger.info("equal encrypted message ...");
                        logger.info("Attestation by...");
                        mv.setViewName("gopay.webtest.front_res_info_trans");
                        /*
                         * Update: Andronicus.Ge
                         * 跨境交易时,在前端展示前台通知得到的值
                         */
                        //===========================================START=========================================
                        if ("7020".equals(transCode)) {
                            fillPageData(request, resp);
                            if ("upload".equals(resp.getFreightType())) {
                                resp.setFreightType("上传");
                            } else if ("add".equals(resp.getFreightType())) {
                                resp.setFreightType("新增");
                            }
                        }

                        if ("8889".equals(transCode)){
                            mv.setViewName("gopay.webtest.front_res_info_trans_8889");
                        }
                        CommonResp resp1 = resp.formatProperty(resp);

//                        String goodsName = resp.getGoodsName();
//                        logger.info("------------goodsName = " + goodsName);
//                        try {
//                            goodsName = new String(new String(goodsName.getBytes("iso8859-1"), "UTF-8"));
//                        } catch (UnsupportedEncodingException e) {
//                            e.printStackTrace();
//                        }
//                        logger.info("------------goodsName = " + goodsName);
//                        resp.setGoodsName(goodsName);

                        logger.info("前台通知详情:" + JSONObject.fromObject(resp1));
                        //===========================================END=========================================
                        mv.addObject("payinfo", resp1);
                        return mv;
                    }

                   
                } 

            }
        }

        return mv;
    }

    private void fillPageData(HttpServletRequest request, CommonResp resp) {
    	String utf8receiver = resp.getReceiver();
    	String utf8orgTxnType = resp.getOrgTxnType();
    	String utf8bankName = resp.getBankName();
    	try {
			resp.setReceiver(new String(utf8receiver.getBytes("ISO-8859-1"), "GBK"));
			resp.setOrgTxnType(new String(utf8orgTxnType.getBytes("ISO-8859-1"), "GBK"));
			resp.setBankName(new String(utf8bankName.getBytes("ISO-8859-1"), "GBK"));
		} catch (UnsupportedEncodingException e) {
			logger.error("编码转换错误!", new IllegalStateException(e));
		}
	}

	private String getVerfiCode(String urlStr) {
        String[] arrSplit = urlStr.split("[?]");
        String id = "";
        for (String string : arrSplit) {
            String[] param = string.split("=");
            if ("id".equals(param[0])) {
                id = param[1];
                break;
            }
        }

        return id;
    }
}
